home *** CD-ROM | disk | FTP | other *** search
Text File | 2002-03-13 | 45.4 KB | 1,153 lines |
- '*****************************************************************************
- '* *
- '* __ _ ___ __ __ _ __ __ *
- '* | \ / \ | | | | \ | \ / \ / \ | / | | | \ *
- '* |__/ | | | | |__ |__/ |__/ | | | |_/ | | |__/ *
- '* | | | | /\ | | | \ | \ |---| | | \ | | | *
- '* | \_/ |/ \| |___ | \ |__/ | | \__/ | \ \_/ | V1.0 *
- '* *
- '* *
- '* written by CHRISTIAN KARGL *
- '* *
- '* Copyright ©2002 *
- '* *
- '* Implementation V0.9ß: (AMOS Backup) 16.Sep 1999 *
- '* V1.00: 6.Okt 2001 - 16.Feb 2002 *
- '* *
- '* Compiled: 16.Feb 2002 (Options: WB, NoScrn, IncLib, IncErr) *
- '* *
- '*****************************************************************************
- '
- '
- ' Linked List for Directory Tree
- ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ' NALLOC (4,+ 0) .... bytes allocated by this item
- ' NXTPTR (4,+ 4) .... address to next item (else NULL)
- ' PARPTR (4,+ 8) .... address to parent dir item (or NULL for root)
- ' FILPTR (4,+12) .... address to sorted file list (or NULL for none)
- ' FLBYTE (4,+16) .... number of bytes for all files
- ' SLBYTE (4,+20) .... number of bytes selected (init with 0)
- ' NFILES (2,+24) .... number of files for this directory item
- ' DIRLVL (1,+26) .... directory level = number of sub-dirs from root
- ' DRSEL$ (1,+27) .... directory selection (same as file selection)
- ' FLSEL$ (N,+28) .... one byte per file: "@" when selected, else "."
- ' TNAME$ (T,+N+28) .. select info, tree structure and directory name
- '
- '
- ' Linked List for Files
- ' ~~~~~~~~~~~~~~~~~~~~~~~
- ' NALLOC (4) ... bytes allocated by this item
- ' NXTPTR (4) ... address to next item (else NULL)
- ' LENGTH (4) ... file length
- ' FNAME$ (?) ... file name
- '
- '
- ' Linked List for Backup History
- ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ' NALLOC (4) ... bytes allocated by this item
- ' NXTPTR (4) ... address to next item (else NULL)
- ' MTEXT$ (?) ... message text to display
- '
- '
- ' Interface programs and variables
- ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ' --+------
- ' 1 | main program
- ' | 0 ... (STR) program version, 3 characters
- ' | 1 ... (STR) compilation date, 11 characters
- ' +----
- ' | Label0 file selection and setup for backup
- ' | 0 ... (STR) root dir
- ' | 1 ... (STR) backup disc labels
- ' | 2 ... (NUM) top position of dir list
- ' | 3 ... (NUM) total number of dirs
- ' | 4 ... (NUM) top position of file list
- ' | 5 ... (NUM) total number of files
- ' | 9 ... (NUM) temp var for all cycle buttons
- ' +----
- ' | Label1 reading source directory (creating dir tree)
- ' +----
- ' | Label2 backup/restore progress panel (with history list)
- ' | 0 ... (NUM) top position of history list
- ' | 1 ... (NUM) total number of history lines
- ' | 2 ... (NUM) number for first message (title, progress)
- ' +----
- ' | Label3 final backup report (buttons to saving history)
- ' +----
- ' | Label4 restore options (with overwrite cycle button)
- ' | 0 ... (STR) custom destination to restore files
- ' +----
- ' | UI BB zonenr,xpos,ypos,textreference (BorderButton)
- ' | UI CB zonenr,xpos,ypos,basemsgnum,totalmsgnum (CycleButton)
- ' --+------
- ' 2 | alert with buttons
- ' | 0 ... (STR) alert text
- ' | 1 ... (NUM) selected button: 1=OKAY, 2=CANCEL
- ' --+------
- ' 3 | information box
- ' | 0 ... (STR) information text
- '
- '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- '
- Set Buffer 20
- '
- Screen Close 0
- 'Break Off : Request Off : Amos Lock : Close Workbench : Wait 100
- '
- Global VERS$,COMP$,PDIR$,C0$,LF$,SQUEST$,SQFLSH$,YTOP,SECS
- Global TREEROOTADRS,MXTREE,FILELISTROOT,MXFILE,NUMDIRS,NUMFILES
- Global NUMBYTES,SELBYTES,SQUEFF,REDIRECT,DISKFREE,DISKUSED,MXDISKBYTE
- Global NUMDISKS,SPLITNUM,HISTROOTADRS,HISTADRS,NUMHIST,BYTEWRIT,BYTEREAD
- Global BKNAME$,SOURCE$,DESTPATH$,DESTFILE$,BKHDRINF$,BKHDRDAT$,NOSIMULATE
- '
- ' init: set version and compilation date, load program data
- '
- PDIR$=Dir$ : VERS$="1.0" : COMP$="16-Feb-2002" : FL$="PowerBackup.Dat"
- '
- If Not Exist(FL$) : Edit : End If : Load FL$ : Resource Bank 16 : Hide
- YTOP=52 : SECS=50 : If Ntsc : YTOP=26 : SECS=60 : End If : OKAY=False
- Resource Screen Open 1,640,74,0 : Screen Display 1,128,YTOP+64,640,74
- Cls 0 : SQUEST$=Chr$(60)+Chr$(54)+Chr$(50)+Chr$(48)+Chr$(46) : C0$=Chr$(0)
- BKHDRINF$=Chr.l$($2BAD4815) : BKHDRDAT$=Chr.l$($E0F63C97) : LF$=Chr$(10)
- SQFLSH$="(00F,1)(70F,1)(F0F,1)(F07,1)(F00,1)(F70,1)(FF0,1)(7F0,1)(0F0,1)(0F7,1)(0FF,1)(07F,1)"
- '
- ' check for OS 2.0+, RAM disk, hard disk, powerpacker.library
- '
- If Deek(Leek(4)+Equ("LIB_VERSION"))<37
- INFO["Sorry, you need OS2.0+ for this program!"]
- Else
- If Not Exist("RAM:")
- INFO["Can't find RAM-Disk! Please check your system!"]
- Else
- If Not Exist("Dh0:")
- INFO["No Hard-disk found! Please reboot your system!"]
- Else : OKAY=True
- If Not Exist("LIBS:powerpacker.library")
- INFO["Need 'powerpacker.library' for compression!"]
- End If
- End If
- End If
- End If
- If OKAY
- '
- ' system okay, check my data
- '
- '+- -+
- '| SNIPPED -> Make your own security check if you want |
- '+- -+
- If OKAY
- '
- ' okay; check for 30 floppy buffers; init main screen
- '
- Erase 20 : FLOPPYADDBUFFERS[0] : NBUFFERS=Param
- If Param<30 : FLOPPYADDBUFFERS[30-NBUFFERS] : End If
- For NR=0 To 31 : Colour NR,0 : Next : Screen Display 1,,YTOP+158,,
- Dialog Open 1,1 : Vdialog$(1,0)=VERS$ : Vdialog$(1,1)=COMP$
- NR=Dialog Run(1) : Wait Vbl : Unpack 11 : Show : Change Mouse 4
- Fade 3 To -1 : Wait 45 : Limit Mouse
- '
- ' main loop (simple, eh?)
- '
- Do
- SL=Dialog(1) : Exit If SL=4
- If SL
- Dialog Freeze 1 : Limit Mouse 128,YTOP To 447,YTOP+231
- On SL Proc MN_ABOUT,MN_BACKUP,MN_RESTORE
- Dialog Unfreeze 1 : Limit Mouse : Wait Vbl : NR=Free
- End If
- Loop : Fade 3 : Wait 45 : Dialog Close : Screen Close 1
- If NBUFFERS<30 : FLOPPYADDBUFFERS[NBUFFERS-30] : End If
- Else
- INFO["Program data corrupted!"]
- End If
- End If
- Dir$=PDIR$ : Erase All : Edit
- 'Dir$=PDIR$ : Erase All : System
- '
- ' Main Procedures
- '
- Procedure MN_ABOUT
- '
- ' init scrolled graphics on hidden screen
- '
- PAGE=4 : Resource Screen Open 2,256,384,0 : Screen Hide 2 : Cls 6
- AD=Start(10) : Unpack 11 : Cls 6,8,4 To 12,70 : Cls 6,238,4 To 240,70
- Get Block 8,8,5,240,64 : Cls 6 : Put Block 8,0,0 : Ink 2,6 : YP=64
- For PG=1 To PAGE
- For LI=0 To 5 : CL=Peek(AD) : LL=Peek(AD+1) : TT$=Peek$(AD+2,LL)
- Add AD,LL+2 : XX=116-4*LL : YY=YP+9 : Add YP,10 : Gr Writing 0
- Ink 0 : Text XX-1,YY,TT$ : Text XX+1,YY,TT$ : Text XX,YY-1,TT$
- Text XX,YY+1,TT$ : Ink CL : Text XX,YY,TT$ : Gr Writing 1
- Next : Add YP,4
- Next : Put Block 8,0,YP : Inc PAGE : Del Block 8 : Screen 1
- Get Block 8,248,4,384,66 : Change Mouse 5 : Ink 0,3 : YP=0
- Set Pattern 30 : Bar 248,4 To 631,69 : Set Pattern 0 : PG=0
- '
- ' scroll info text; wait for key or mouse button each page
- '
- Do : Inc PG
- For LI=0 To 63 : Inc YP
- Screen Copy 2,4,YP,230,YP+64 To 1,12,5 : Wait Vbl
- Next : Exit If PG=PAGE
- Clear Key : Repeat : Until Mouse Click or Inkey$>""
- Loop : Change Mouse 4 : Put Block 8 : Del Block 8 : Wait Vbl
- Screen Close 2
- End Proc
- Procedure MN_BACKUP
- '
- ' init file selection; appear screen
- '
- SOURCE$="" : BKNAME$="Backup"
- REDIRECT=False : INSTALL=False : TREEROOTADRS=0 : FILELISTROOT=0
- NUMDIRS=0 : MXTREE=0 : MXFILE=0 : NUMFILES=0 : NUMBYTES=0 : SELBYTES=0
- SQUEFF=0 : Resource Screen Open 2,640,232,0 : Cls 0 : Pen 2
- Paper 6 : Screen Display 2,128,YTOP+248,640,232 : Reserve Zone 2
- Set Zone 1,32,48 To 319,175 : Set Zone 2,368,48 To 607,175 : REDRAW=8
- Dialog Open 2,1,16,4096 : Vdialog$(2,0)=SOURCE$ : Vdialog$(2,1)=BKNAME$
- Vdialog(2,3)=0 : Vdialog(2,5)=0 : SL=Dialog Run(2,0) : CONTINUE=1
- For YP=240 To 0 Step -8 : Screen Display 2,,YTOP+YP,, : Wait Vbl : Next
- '
- ' main backup selection loop
- '
- Repeat
- '
- ' check for click on list areas; else check dialog
- '
- If Mouse Click
- MZ=Mouse Zone : PS=(Y Screen(Y Mouse)-48)/8
- If MZ=1
- If DRTOP+PS<MXTREE : MK=Mouse Key
- If MK=1 : SL=13 : Else If MK=2 : SL=14 : End If
- End If
- Else If MZ=2
- If FLTOP+PS<MXFILE : SL=15 : End If
- End If
- Else
- SL=Dialog(2)
- End If
- '
- ' check for selection
- '
- If SL
- Dialog Freeze 2 : Window 0 : Wait Vbl
- If SL=1
- '
- ' change source dir: if exist read new source directory
- '
- TT$=Path$(Rdialog$(2,1)+"/")
- If Exist(TT$) : MT=MXTREE
- ND=NUMDIRS : NF=NUMFILES : NB=NUMBYTES : SB=SELBYTES
- Get Block 8,0,0,640,232 : Ink 0,3 : Set Pattern 30
- Bar 0,0 To 639,231 : Set Pattern 0 : Dialog Open 3,1
- SL=Dialog Run(3,1) : MAKE_DIRTREE[TT$] : Dialog Close 3
- '
- ' delete old tree and update vars, else restore old values
- '
- If Param>0 : SOURCE$=TT$ : DRTOP=0 : FLTOP=0 : REDRAW=7
- AD=TREEROOTADRS : TREEROOTADRS=Param : DELETE_DIRTREE[AD]
- FILELISTROOT=TREEROOTADRS : MXFILE=Deek(FILELISTROOT+24)
- Else : MXTREE=MT
- NUMDIRS=ND : NUMFILES=NF : NUMBYTES=NB : SELBYTES=SB
- If Param : INFO["Sorry, I'm low on memory!"]
- Else : INFO["Directory tree setup aborted."] : End If
- End If : Put Block 8 : Del Block 8 : Gosub DISPLAY : Wait Vbl
- End If : Dialog Update 2,1,SOURCE$
- Else If SL=2
- '
- ' remove path character; ask if user wants to redirect backup
- '
- TT$=Rdialog$(2,2) : PS=Instr(TT$,">>")+2
- If PS=2
- BKNAME$=TT$-" "-"/"-":" : REDIRECT=False
- Else If PS>3
- If Exist(Mid$(TT$,PS))
- ALERT["Redirect backup to '"+Mid$(TT$,PS)+"' ?"]
- If Param=1 : BKNAME$=TT$ : REDIRECT=True : End If
- End If
- End If : Dialog Update 2,2,BKNAME$
- Else If SL<6
- DRTOP=Vdialog(2,2) : REDRAW=1 : Gosub DISPLAY
- Else If SL<9
- FLTOP=Vdialog(2,4) : REDRAW=2 : Gosub DISPLAY
- Else If SL=9
- INSTALL=Rdialog(2,9) : REDRAW=2 : Gosub DISPLAY
- Else If SL=10
- SQUEFF=Rdialog(2,10)/2 : REDRAW=8 : Gosub DISPLAY
- Else If SL<13
- '
- ' check to leave selection loop
- '
- CONTINUE=SL-12
- If SL=10 and SELBYTES=0
- INFO["No data selected to backup!"] : CONTINUE=1
- Else If REDIRECT
- TT$=Disc Info$(Mid$(BKNAME$,Instr(BKNAME$,">>")+2))
- MX=Val(Mid$(TT$,Instr(TT$,":")+1)) : NR=SELBYTES
- If SQUEFF : NR=(NR/100)*Asc(Mid$(SQUEST$,SQUEFF)) : End If
- '
- ' check if enough disc space when redirecting
- '
- If MX<NR
- INFO["Not enough disc space to redirect!"] : CONTINUE=1
- Else If MX<104*(NR/100)
- ALERT["Free disc space may be insufficent. Continue?"]
- If Param>1 : CONTINUE=1 : End If
- End If
- End If
- Else If SL=13
- '
- ' left click on tree area -> select dir
- '
- MOVE_TO_ENTRY[TREEROOTADRS,DRTOP+PS]
- If Param : ADRS=Param : REDRAW=3
- SNEW=110-Peek(ADRS+27) : MX=Peek(ADRS+26)
- Repeat
- NR=Deek(ADRS+24)+1 : AD=ADRS+27
- While NR : Poke AD,SNEW : Inc AD : Dec NR : Wend
- If SNEW=64 : NR=Leek(ADRS+16) Else NR=0 : End If
- Add SELBYTES,NR-Leek(ADRS+20) : Loke ADRS+20,NR
- ADRS=Leek(ADRS+4) : Exit If ADRS=0
- Until Peek(ADRS+26)<=MX : Gosub DISPLAY
- End If
- Else If SL=14
- '
- ' right click on tree area -> display files
- '
- MOVE_TO_ENTRY[TREEROOTADRS,DRTOP+PS]
- If Param : FILELISTROOT=Param : FLTOP=0
- MXFILE=Deek(Param+24) : REDRAW=7 : Gosub DISPLAY
- End If
- Else If SL=15
- '
- ' click on file area -> select file
- '
- MOVE_TO_ENTRY[Leek(FILELISTROOT+12),FLTOP+PS]
- If Param
- BYTE=Leek(Param+8) : ADRS=FILELISTROOT : REDRAW=3
- AD=ADRS+FLTOP+PS+28 : SNEW=110-Peek(AD) : Poke AD,SNEW
- If SNEW=46 : BYTE=-BYTE : End If : Add SELBYTES,BYTE
- NR=Leek(ADRS+20)+BYTE : If NR : SL=64 Else SL=46 : End If
- Loke ADRS+20,NR : Poke ADRS+27,SL : Gosub DISPLAY
- End If
- End If : Dialog Unfreeze 2 : Wait Vbl
- End If
- Until CONTINUE<1 : Dialog Close 2
- '
- ' if not aborted, check for redirection
- '
- If CONTINUE : DESTPATH$="DF0:"
- If REDIRECT : PS=Instr(BKNAME$,">>") : TT$=Mid$(BKNAME$,PS+2)
- BKNAME$=Left$(BKNAME$,PS-1) : NR=Asc(Right$(TT$,1)) : Ink 0,3
- If NR<>47 and NR<>58 : TT$=TT$+"/" : End If : DESTPATH$=TT$
- Set Pattern 30 : Bar 0,0 To 639,231 : Set Pattern 0 : BYTE=488
- NR=1760 : DISKUSED=0 : Dialog Open 3,1 : SL=Dialog Run(3,6)
- Do
- SL=Dialog(3) : Exit If SL>3
- If SL
- If Rdialog(3,1) : NR=3520 Else NR=1760 : End If
- If Rdialog(3,2) : BYTE=512 Else BYTE=488 : End If
- MX=BYTE*(NR-4) : Window 0 : Print At(61,13);Lsstr$(MX/1024,4)
- SB=Min(1024*Rdialog(3,3),MX/2) : Dialog Update 3,3,SB/1024
- End If
- Loop : CONTINUE=(SL=4)
- MXDISKBYTE=BYTE*((1730*NR)/1760-6) : Dialog Close 3 : Wait Vbl
- End If
- If CONTINUE
- '
- ' init history messages
- '
- Timer=0 : HISTROOTADRS=0 : HISTADRS=0 : NUMHIST=0 : DRTOP=0
- GTDATETIME : HISTORYENTRY["Starting backup: "+Param$] : NF=0
- Dec SQUEFF : HISTORYENTRY["Writing to: '"+DESTPATH$+"'"+LF$]
- '
- ' calculate number of selected files
- '
- NUMDISKS=1 : BYTEWRIT=0 : BYTEREAD=0 : MX=0 : ADRS=TREEROOTADRS
- While ADRS : AD=ADRS+28 : NR=Deek(ADRS+24) : ADRS=Leek(ADRS+4)
- While NR : Add MX,Peek(AD)/64 : Inc AD : Dec NR : Wend
- Wend : TT$=Chr.l$(MX xor $A45B918D)+Chr.l$(MX xor $C2370E6F)
- '
- ' init backup dialog, ask for first disc and write init header
- '
- Fade 2 : Wait 30 : Cls 0 : Dialog Open 2,1 : Vdialog(2,0)=0
- Vdialog(2,1)=NUMHIST : Vdialog(2,2)=28 : RN=Dialog Run(2,2)
- DISPLAY_HISTORY[0] : Fade 3 To 1 : Wait 45 : REQUEST_BACKDISC[1]
- DISKUSED=SB+16 : Print #1,"PPBACK10"+TT$; : ADRS=TREEROOTADRS
- '
- ' add required data and program to start from first disc
- '
- If INSTALL : Add DISKUSED,169824
- SOURCE$=Extpath$(PDIR$) : TT$="powerpacker.library"
- Mkdir "Libs" : Trap File Copy "LIBS:"+TT$ To "Libs/"+TT$
- TT$=Command Name$ : File Copy SOURCE$+TT$ To TT$
- TT$=TT$+".info" : File Copy SOURCE$+TT$ To TT$
- TT$="PowerBackup.Dat" : File Copy SOURCE$+TT$ To TT$
- HISTORYENTRY["Copying program and data to first disc."+LF$]
- End If
- '
- ' read through directory tree and backup selected files
- '
- While ADRS : FLADRS=Leek(ADRS+12) : Loke ADRS+12,0
- If FLADRS>0 and Peek(ADRS+27)=64 : CREATE_DIRTREE_PATH[ADRS]
- TT$=Param$ : FADR=FLADRS : NR=Deek(ADRS+24) : AD=ADRS+28
- While NR
- If Peek(AD)=64 : PS=Max(NUMHIST-8,0)
- BACKUP_FILE[TT$+Peek$(FADR+12,Leek(FADR),C0$)]
- '
- ' update dialog
- '
- If Vdialog(2,0)=PS
- DRTOP=Max(NUMHIST-8,0) : DISPLAY_HISTORY[DRTOP]
- Else If Dialog(2)
- DRTOP=Vdialog(2,0) : DISPLAY_HISTORY[DRTOP]
- End If
- Dialog Update 2,1,DRTOP,8,NUMHIST : Inc NF
- Vdialog(2,1)=NUMHIST : Dialog Update 2,2,0,NF,MX
- End If : Inc AD : Dec NR : FADR=Leek(FADR+4)
- Wend
- End If : DELETE_LIST[FLADRS] : ADRS=Leek(ADRS+4)
- Wend
- '
- ' done; close file and display final report; save/delete history
- '
- Print #1,BKHDRINF$;"¦END"; : Close 1 : Ink 0,3 : Set Pattern 30
- Bar 0,0 To 639,231 : Set Pattern 0 : SL=Timer/SECS : NR=SL mod 60
- Dialog Close 2 : Wait 5 : Dialog Open 2,1 : RN=Dialog Run(2,3)
- Wait Vbl : GTDATETIME : HISTORYENTRY["Finished backup: "+Param$]
- SL=SL/60 : BYTEREAD=Max(BYTEREAD,100) : TT$=Lsstr$(NUMDISKS,4)
- HISTORYENTRY[Resource$(34)+Space$(10)+TT$] : Print At(55,11);TT$
- TT$=Lsstr$(BYTEWRIT,8) : HISTORYENTRY[Resource$(35)+" "+TT$]
- Print At(51,12);TT$ : TT$=Lsstr$(BYTEWRIT/(BYTEREAD/100),3)+"%"
- HISTORYENTRY[Resource$(36)+Space$(6)+TT$] : Print At(55,13);TT$
- TT$=Lzstr$(SL/60,2)+":"+Lzstr$(SL mod 60,2)+":"+Lzstr$(NR,2)
- HISTORYENTRY[Resource$(37)+Space$(7)+TT$] : Print At(51,14);TT$
- Repeat : SL=Dialog(2) : Until SL>0 : Dialog Close 2 : Wait 5
- If SL=1 : HISTORY_SAVE : End If : DELETE_LIST[HISTROOTADRS]
- End If
- End If
- '
- ' delete directory tree
- '
- For YP=0 To 240 Step 8 : Screen Display 2,,YTOP+YP,, : Wait Vbl : Next
- Screen Close 2 : DELETE_DIRTREE[TREEROOTADRS] : Pop Proc
- '
- '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ' redraw backup selection display
- '
- DISPLAY:
- NR=SELBYTES : If INSTALL : AD=169824 Else AD=0 : End If
- If SQUEFF : NR=(NR/100)*Asc(Mid$(SQUEST$,SQUEFF)) : End If
- Add NR,AD : NUMDDISK=NR/858880+1 : NUMHDISK=NR/1717760+1
- Print At(11,23);Lsstr$(NUMDIRS,6);At(27,23);Lsstr$(NUMFILES,6)
- Print At(43,23);Lsstr$(NUMBYTES,9);At(66,23);Lsstr$(SELBYTES,9)
- Print At(39,25);Lsstr$(NUMDDISK,4);At(48,25);Lsstr$(NUMHDISK,4)
- '
- ' check other updates
- '
- If REDRAW and 1 : DISPLAY_DIRS[DRTOP] : End If
- If REDRAW and 2 : DISPLAY_FILES[FLTOP] : End If
- If REDRAW and 4 : Dialog Update 2,1,SOURCE$
- Vdialog(2,3)=MXTREE : Dialog Update 2,5,DRTOP,16,MXTREE
- Vdialog(2,5)=MXFILE : Dialog Update 2,8,FLTOP,16,MXFILE
- End If : REDRAW=0
- Return
- '
- End Proc
- Procedure MN_RESTORE
- '
- ' init restore options; appear screen
- '
- Resource Screen Open 2,640,232,0
- Cls 0 : Paper 6 : Pen 2 : Screen Display 2,128,YTOP+248,640,232
- DESTPATH$="" : Dialog Open 2,1 : Vdialog$(2,0)="" : SL=Dialog Run(2,4)
- For YP=240 To 0 Step -8 : Screen Display 2,,YTOP+YP,, : Wait Vbl : Next
- '
- ' wait for actions; read settings
- '
- Repeat
- SL=Dialog(2)
- If SL=3 : TT$=Rdialog$(2,3) : OK=Exist(TT$)
- If OK=False : ALERT["Directory not found! Create?"]
- If Param=1 : CREATE_DIR[TT$] : OK=True : End If
- End If
- If OK : DESTPATH$=Extpath$(TT$)
- Dialog Update 2,2,1 : Dialog Update 2,3,TT$
- End If
- End If
- Until SL>4 : NOSIMULATE=(Rdialog(2,1)=0)
- REDIRECT=Rdialog(2,2) : OVRTYP=Rdialog(2,4)/2 : Dialog Close 2
- If Not NOSIMULATE : REDIRECT=False : OVRTYP=2 : End If
- '
- ' if not aborted: start dialog and request first disc
- '
- If SL=5
- Fade 2 : Wait 30 : Cls 0 : Dialog Open 2,1 : Vdialog(2,0)=0
- Vdialog(2,1)=0 : Vdialog(2,2)=46 : SL=Dialog Run(2,2) : Wait Vbl
- Dialog Freeze 2 : Fade 3 To 1 : Wait 45 : Dialog Open 7,3
- Vdialog$(7,0)="Please insert first disc into drive DF0:"
- SL=Dialog Run(7) : Repeat : Until Exist("DF0:") : Dialog Close 7
- Wait Vbl : SOURCE$="DF0:Backup0001.DAT0" : TT$=Disc Info$("DF0:")
- BKNAME$=Left$(TT$,Instr(TT$,":")-1) : PS=Instr(BKNAME$,"_#")
- '
- ' check header informations
- '
- If PS : BKNAME$=Left$(BKNAME$,PS-1)
- If Exist(SOURCE$) : Open In 1,SOURCE$ : HD$=Input$(1,8)
- TT$=Input$(1,8) : CHCK=Asc.l(Right$(TT$,4)) xor $C2370E6F
- NUMFILES=Asc.l(Left$(TT$,4)) xor $A45B918D : NUMDISKS=1
- '
- ' if header okay, init history messages
- '
- If HD$="PPBACK10" and NUMFILES=CHCK : Timer=0 : HTOP=0
- HISTROOTADRS=0 : HISTADRS=0 : NUMHIST=0 : SPLITNUM=0
- GTDATETIME : HISTORYENTRY["Starting restore: "+Param$]
- '
- ' check redirection and simulation; unfreeze dialog
- '
- If NOSIMULATE : TT$="Writing data to "
- If REDIRECT : TT$=TT$+"'"+DESTPATH$+"'."
- Else : TT$=TT$+"original location." : End If
- Else : TT$="Simulating file restoration." : End If
- HISTORYENTRY[TT$+LF$] : DISPLAY_HISTORY[0] : FLOKAY=0
- FLERRS=0 : FLSKIP=0 : FLOVER=0 : Vdialog(2,1)=NUMHIST
- Dialog Update 2,1,DRTOP,8,NUMHIST : Dialog Unfreeze 2
- '
- ' main restore loop; get next file infos; check headers
- '
- For FL=1 To NUMFILES : SL=Max(NUMHIST-8,0)
- If Input$(1,4)=BKHDRINF$ : TT$=Input$(1,4)
- Exit If TT$="¦END" : INFO$=TT$+Input$(1,22)
- FLEN=Asc.w(Input$(1,2)) : FILE$=Input$(1,FLEN)
- If Input$(1,4)=BKHDRDAT$ : OK=True
- '
- ' check dir, check existing files, restore file
- '
- If NOSIMULATE
- If REDIRECT
- FILE$=DESTPATH$+Mid$(FILE$,Instr(FILE$,":")+1)
- End If
- If Exist(FILE$) : OK=(OVRTYP>1)
- If OVRTYP=1
- ALERT["Overwrite file?"] : OK=(Param=1)
- End If : If OK : Inc FLOVER : End If
- End If
- End If
- If OK : RESTOR_FILE[FILE$,INFO$]
- If Param : Inc FLOKAY Else Inc FLERRS : End If
- Else : Inc FLSKIP
- FILE$="Skipping '"+FILE$+"'" : Gosub SKIPDATA
- End If
- Else : Inc FLERRS
- FILE$="Error! Missing header." : Gosub SKIPDATA
- End If
- Else : Inc FLERRS
- FILE$="Error! Missing header." : Gosub SKIPDATA
- End If
- '
- ' update dialog sliders
- '
- If Vdialog(2,0)=SL
- DRTOP=Max(NUMHIST-8,0) : DISPLAY_HISTORY[DRTOP]
- Else If Dialog(2)
- DRTOP=Vdialog(2,0) : DISPLAY_HISTORY[DRTOP]
- End If
- Vdialog(2,1)=NUMHIST : Dialog Update 2,1,DRTOP,8,NUMHIST
- Dialog Update 2,3,0,FL,NUMFILES : Wait Vbl
- Next
- '
- ' done; display final report; save/delete history
- '
- Dialog Freeze 2 : SL=Timer/SECS : GTDATETIME
- HISTORYENTRY["Finished restore: "+Param$] : Ink 0,3
- Set Pattern 30 : Bar 0,0 To 639,231 : Set Pattern 0
- Dialog Open 3,1 : RN=Dialog Run(3,5) : Wait Vbl
- TT$=Lsstr$(FLOKAY,6) : HISTORYENTRY[Resource$(49)+" "+TT$]
- Print At(51,11);TT$ : TT$=Lsstr$(FLSKIP,6) : NR=SL mod 60
- HISTORYENTRY[Resource$(50)+" "+TT$] : Print At(51,12);TT$
- TT$=Lsstr$(FLOVER,6) : HISTORYENTRY[Resource$(51)+" "+TT$]
- Print At(51,13);TT$ : TT$=Lsstr$(FLERRS,6) : SL=SL/60
- HISTORYENTRY[Resource$(52)+" "+TT$] : Print At(51,14);TT$
- TT$=Lzstr$(SL/60,2)+":"+Lzstr$(SL mod 60,2)+":"+Lzstr$(NR,2)
- HISTORYENTRY[Resource$(53)+" "+TT$] : Print At(49,15);TT$
- Repeat : SL=Dialog(3) : Until SL>0 : Dialog Close 3 : Wait 5
- If SL=1 : HISTORY_SAVE : End If : DELETE_LIST[HISTROOTADRS]
- Else
- INFO["First backup data has corrupted file header!"]
- End If : Close 1
- Else
- INFO["Can't find first backup data file!"]
- End If
- Else
- INFO["Wrong backup disc name format!"]
- End If
- Dialog Close 2
- End If
- '
- ' done; remove screen
- '
- For YP=0 To 240 Step 8 : Screen Display 2,,YTOP+YP,, : Wait Vbl : Next
- Screen Close 2 : Pop Proc
- '
- ' special sub routine for skipping current data to next file
- '
- SKIPDATA:
- Change Mouse 5 : Flash 18,SQFLSH$ : Cls 6,56,104 To 584,128
- Wait 5 : HISTORYENTRY["("+Ct Time$(Current Time)+") "+FILE$]
- TT$="Searching for header information." : HISTORYENTRY[" "+TT$+LF$]
- PS=Len(FILE$) : If PS>66 : FILE$=Cutstr$(FILE$,11 To PS-55) : End If
- Print At(7,13);FILE$;At(9,14);TT$;".." : Reserve As Work 20,1024
- AD=Start(20) : PS=Pof(1) : SZ=Lof(1)-PS
- '
- ' read bytes of file; check for end of file; set file position
- '
- Do
- If Eof(1) : Inc SPLITNUM
- Close 1 : Wait 5 : Right$(SOURCE$,1)=Chr$(SPLITNUM+48)
- If Not Exist(SOURCE$)
- Inc NUMDISKS : REQUEST_RESTDISC[NUMDISKS]
- End If : Open In 1,SOURCE$ : Wait 5 : PS=0 : SZ=Lof(1)
- End If
- Poke$ AD,Input$(1,Min(SZ,1024)) : Wait Vbl
- SZ=Max(SZ-1024,0) : FLEN=Hunt(AD To AD+1024,BKHDRINF$)
- If FLEN>0 : Add PS,FLEN-AD : Exit : End If : Add PS,1024
- Loop : Pof(1)=PS : Flash Off
- Colour 18,$C60 : Change Mouse 4 : Erase 20 : Wait Vbl
- Return
- '
- End Proc
- Procedure GTDATETIME
- '
- ' formated date & time: "www dd-mmm-yyyy at hh:mm:ss."
- '
- DATE=Current Date : TT$=" at "+Ct Time$(Current Time)+"."
- TT$=Left$(Cd Date$(DATE),11)+Lsstr$(Cd Year(DATE),4)+TT$
- End Proc[TT$]
- '
- ' Backup Procedures
- '
- Procedure DISPLAY_DIRS[DTOP]
- '
- ' display directory tree starting at DTOP
- '
- MOVE_TO_ENTRY[TREEROOTADRS,DTOP] : AD=Param
- If AD : ITEM=0 : YP=6
- '
- ' okay, print next 16 entries
- '
- While ITEM<16
- TT$=Peek$(AD+Deek(AD+24)+28,Leek(AD),C0$) : YY=8*YP
- If AD=FILELISTROOT : Paper 4 Else Paper 0 : End If
- If Peek(AD+27)=64 : Pen 1 Else Pen 3 : End If : PS=1
- Do
- A$=Mid$(TT$,PS,1) : Inc PS : XX=16*PS
- Exit If A$="»" : NR=Instr("|+-",A$)
- If NR : Resource Unpack NR+35,XX,YY
- Else Cls 0,XX,YY To XX+16,YY+8 : End If
- Loop : NR=40-2*PS : A$=Mid$(TT$,Min(PS,NR))
- '
- ' >>> PROBLEM: DirName + DirStructure too long ??
- '
- Print At(2*PS,YP);A$;Paper$(0);Space$(NR-Len(A$));
- Inc YP : Inc ITEM : AD=Leek(AD+4) : Exit If AD=0
- Wend : If ITEM<16 : Cls 0,32,8*YP To 320,176 : End If
- Wait Vbl : Paper 6 : Pen 2
- End If
- End Proc
- Procedure DISPLAY_FILES[FTOP]
- '
- ' display next 16 file names starting at FTOP
- '
- MOVE_TO_ENTRY[Leek(FILELISTROOT+12),FTOP]
- If Param : ADRS=Param
- ITEM=0 : YP=6 : Paper 0 : STRT=FILELISTROOT+FTOP+28
- While ITEM<14
- FL$=Peek$(ADRS+12,22,C0$) : FLEN=Leek(ADRS+8)
- If Peek(STRT+ITEM)=64 : Pen 1 Else Pen 3 : End If
- Print At(46,YP);FL$;Space$(22-Len(FL$));Lsstr$(FLEN,8)
- Inc YP : ADRS=Leek(ADRS+4) : Exit If ADRS=0 : Inc ITEM
- Wend : If ITEM<14 : Cls 0,368,8*YP To 608,160 : End If
- Paper 6 : Pen 2
- Else
- Cls 0,368,48 To 608,160
- End If
- End Proc
- Procedure REQUEST_BACKDISC[DN]
- '
- ' wait for next disc
- '
- TT$=Lzstr$(DN,4) : SPLITNUM=0 : DISKUSED=0 : Dir$="RAM:"
- NAME$=BKNAME$+"_#"+TT$ : DESTFILE$="Backup"+TT$+".DAT0"
- If REDIRECT
- '
- ' redirecting -> create new directory for next floppy
- '
- TT$=DESTPATH$+NAME$ : DISKFREE=MXDISKBYTE
- If Not Exist(TT$) : Mkdir TT$ : End If : Dir$=TT$
- Else
- '
- ' else wait for a new real floppy disc in drive DF0:
- '
- Get Block 8,0,0,640,232 : Wait Vbl : Ink 0,3
- Set Pattern 30 : Bar 0,0 To 639,231 : Set Pattern 0
- Do
- '
- ' remove any disc in drive DF0: first
- '
- If Exist("DF0:") : Dialog Open 3,3
- Vdialog$(3,0)="Please remove disc from DF0:" : RR=Dialog Run(3)
- Wait Vbl : Repeat : Until Not Exist("DF0:") : Dialog Close 3
- End If
- '
- ' ask for next backup disc; get disc infos; ask to use it
- '
- Dialog Open 3,3
- Vdialog$(3,0)="Please insert backup disc"+Str$(DN)+" into DF0:"
- RR=Dialog Run(3) : Wait Vbl : Repeat : Until Exist("DF0:")
- Dialog Close 3 : Wait Vbl : TT$=Disc Info$("DF0:")
- DF$=Right$(TT$,10)-" " : TT$=Left$(TT$,Len(TT$)-10)
- ALERT[DF$+" bytes free on disc '"+TT$+"'. Continue?"]
- If Param=1
- '
- ' relabel disc (DOS function call returns 0 on failure)
- '
- DISKFREE=Val(DF$) : TT$="DF0:" : Dreg(1)=Varptr(TT$)
- Dreg(2)=Varptr(NAME$) : Exit If Doscall(Lvo("Relabel"))
- INFO["ERROR! Can't relabel disc in drive DF0:"] : Clear Key
- End If : Wait 10
- Loop : Put Block 8 : Del Block 8 : Wait Vbl : Dir$="DF0:"
- End If : Trap Kill DESTFILE$ : Open Out 1,DESTFILE$
- '
- End Proc
- Procedure BACKUP_FILE[FILE$]
- '
- ' write file FILE$ (with full path) into backup file
- '
- HISTORYENTRY["("+Ct Time$(Current Time)+") Loading '"+FILE$+"'"]
- Examine Object FILE$ : FLSIZE=Object Size : FLSUMM=0 : SQSIZE=0
- SQSUMM=0 : Cls 6,56,104 To 584,128 : Print At(7,13);Right$(FILE$,66)
- '
- ' check for data to load
- '
- If FLSIZE>0 : BLEN=(FLSIZE+3) and $FFFFFFFC
- Print At(9,14);"Loading... "; : Trap Reserve As Work 20,BLEN
- If Errtrap=0
- AD=Start(20) : Fill AD To AD+BLEN,0 : Bload FILE$,AD
- Wait 5 : FLSUMM=Bank Checksum(20) : Print "Done."
- '
- ' squash file with powerpacker.library ?
- '
- If SQUEFF>=0 and FLSIZE>99 : Change Mouse 5
- Flash 18,SQFLSH$ : Print At(11,15);"Squashing... ";
- Wait 5 : Trap Pptodisk "RAM:Temp",20,SQUEFF : Flash Off
- Colour 18,$C60 : Change Mouse 4 : Wait Vbl : SQSIZE=FLSIZE
- If Errtrap=0
- Open In 2,"Ram:Temp" : SQSIZE=Lof(2) : Close 2 : Wait Vbl
- BLEN=(SQSIZE+3) and $FFFFFFFC : Reserve As Work 20,BLEN
- AD=Start(20) : Fill AD To AD+BLEN,0 : Bload "Ram:Temp",AD
- End If
- End If
- End If
- End If
- '
- ' print messages and save data from bank 20 to backup file
- '
- If Length(20)>0
- If FLSIZE=0
- INFO$="Storing empty file" : Locate 9,14 : HMSG$=INFO$
- Else
- SZ$=" ("+Mid$(Str$(FLSIZE),2)+" bytes)"
- If SQSIZE=0 : INFO$="Saving original file" : Locate 11,15
- HMSG$=INFO$+SZ$ : SQSUMM=FLSUMM : SQSIZE=FLSIZE
- Else If SQSIZE<FLSIZE
- SQSUMM=Bank Checksum(20) : INFO$="Saving squashed file"
- TT$=Mid$(Str$(Int(SQSIZE/(FLSIZE/1000.0))/10.0),2)+"% ="
- HMSG$=INFO$+" ("+TT$+Str$(SQSIZE)+"/"+Mid$(SZ$,3)
- Else
- INFO$="FAILED! Saving original file" : SQSIZE=FLSIZE
- HMSG$="Squashing "+INFO$+SZ$ : SQSUMM=FLSUMM
- End If
- End If
- Print INFO$;"... "; : FL=Len(FILE$) : FLPY=(DESTPATH$="DF0:")
- Add DISKUSED,36+FL : Add BYTEREAD,FLSIZE : Add BYTEWRIT,SQSIZE
- Print #1,BKHDRINF$+Chr.l$(FLSIZE)+Chr.l$(FLSUMM)+Chr.l$(SQSIZE);
- Print #1,Chr.l$(SQSUMM)+Chr.l$(Object Date)+Chr.l$(Object Time);
- Print #1,Chr.w$(Object Protection)+Chr.w$(FL)+FILE$+BKHDRDAT$;
- '
- ' check disc space and file limit (216K); write data to backup file
- '
- While SQSIZE>0
- If FLPY : DISKUSED=DISKFREE-Dfree : End If
- If DISKFREE-DISKUSED<4096 : Close 1
- Wait 5 : Inc NUMDISKS : REQUEST_BACKDISC[NUMDISKS]
- End If
- If Lof(1)>221184 : Inc SPLITNUM
- Right$(DESTFILE$,1)=Chr$(SPLITNUM+48) : Close 1
- Wait 5 : Trap Kill DESTFILE$ : Open Out 1,DESTFILE$
- End If : BLEN=Min(SQSIZE,1024)
- Print #1,Peek$(AD,BLEN); : Add AD,BLEN : Add SQSIZE,-BLEN
- Add DISKUSED,BLEN : Dialog Update 2,3,0,DISKUSED/64,DISKFREE/64
- Wend : Print "Done." : Wait 20
- Else
- HMSG$="FAILED! Not enough memory to load file!" : Print HMSG$
- End If : HISTORYENTRY[" "+HMSG$+LF$]
- '
- End Proc
- '
- ' Restore Procedures
- '
- Procedure CREATE_DIR[DR$]
- '
- ' create directory structure DR$ if not exist
- '
- DR$=Extpath$(DR$) : PS=Instr(DR$,"/")
- While PS : TT$=Left$(DR$,PS-1)
- If Not Exist(TT$) : Mkdir TT$ : End If : PS=Instr(DR$,"/",PS+1)
- Wend
- End Proc
- Procedure REQUEST_RESTDISC[DN]
- '
- ' wait for next backup disc in drive DF0:
- '
- Get Block 8,0,0,640,232 : Wait Vbl : Ink 0,3
- Set Pattern 30 : Bar 0,0 To 639,231 : Set Pattern 0
- TT$=Lzstr$(DN,4) : SPLITNUM=0 : NAME$=BKNAME$+"_#"+TT$+":"
- Do
- '
- ' remove previous backup disc from drive DF0:
- '
- Dialog Open 3,3 : Vdialog$(3,0)="Please remove disc from DF0:"
- RR=Dialog Run(3) : Repeat : Until Not Exist("DF0:") : Dialog Close 3
- '
- ' ask for next backup disc; check for backup file
- '
- Dialog Open 3,3 : Vdialog$(3,0)="Please insert '"+NAME$+"' into DF0:"
- RR=Dialog Run(3) : Repeat : Until Exist(NAME$) : Dialog Close 3
- '
- ' check for required backup file
- '
- SOURCE$="DF0:Backup"+TT$+".DAT0" : Exit If Exist(SOURCE$)
- INFO["Hey, can't find backup data what I expected!"]
- Loop : Put Block 8 : Del Block 8 : Wait Vbl
- '
- End Proc
- Procedure RESTOR_FILE[FILE$,INFO$]
- '
- ' update history; extract file informations
- '
- Reserve As Work 20,26
- AD=Start(20) : Poke$ AD,INFO$ : FLSIZE=Leek(AD) : FLSUMM=Leek(AD+4)
- SQSIZE=Leek(AD+8) : SQSUMM=Leek(AD+12) : FLDATE=Leek(AD+16)
- FLTIME=Leek(AD+20) : FLPROT=Deek(AD+24) : Cls 6,56,104 To 584,128
- Erase 20 : Print At(7,13);Right$(FILE$,66) : Locate 9,14
- HISTORYENTRY["("+Ct Time$(Current Time)+") Loading '"+FILE$+"'"]
- '
- ' special check for empty files
- '
- If FLSIZE=0 : OKAY=True
- MS$="Okay." : HMSG$="Saving empty file... " : Print HMSG$;
- If NOSIMULATE
- TT$=Path$(FILE$) : If Not Exist(TT$) : CREATE_DIR[TT$] : End If
- MS$="Failed!" : OKAY=False : Trap Open Out 2,FILE$
- If Errtrap=0 : Close 2 : Set Object Date FILE$,FLDATE,FLTIME
- Protect Object FILE$,FLPROT : MS$="Done." : OKAY=True
- End If
- End If : HMSG$=HMSG$+MS$ : Print MS$ : Wait 5
- Else
- SZ=SQSIZE : BLEN=(SZ+3) and $FFFFFFFC : Print "Loading data... ";
- Reserve As Work 20,BLEN : AD=Start(20) : Fill AD To AD+BLEN,0
- Repeat
- '
- ' check next backup file or new disc ?
- '
- If Eof(1) : Close 1 : Wait 5
- Inc SPLITNUM : Right$(SOURCE$,1)=Chr$(SPLITNUM+48)
- If Not Exist(SOURCE$)
- Inc NUMDISKS : REQUEST_RESTDISC[NUMDISKS]
- End If : Open In 1,SOURCE$
- End If
- '
- ' writing data into temporary bank 20
- '
- Poke$ AD,Input$(1,Min(SZ,1024)) : Wait Vbl : SZ=Max(SZ-1024,0)
- Add AD,1024 : Dialog Update 2,2,0,(SQSIZE-SZ)/256,SQSIZE/256
- Until SZ<1
- Wait 10 : Print "Done." : Locate 11,15 : HMSG$="" : OKAY=False
- '
- ' check if data are (power) packed -> try to unpack it
- '
- If SQSIZE<FLSIZE : HMSG$="Unpacking... " : Print HMSG$;
- If Bank Checksum(20)=SQSUMM
- Change Mouse 5 : Flash 0,SQFLSH$ : Trap Ppunpack 20 To 22
- Wait 5 : Flash Off : Colour 0,0 : Change Mouse 4
- '
- ' if unpacking successful, replace original data in bank 20
- '
- If Errtrap=0 : BLEN=(FLSIZE+3) and $FFFFFFFC
- Erase 20 : Reserve As Work 20,BLEN : AD=Start(22)
- Copy AD,AD+BLEN To Start(20) : Wait 5 : Erase 22
- Else : FLSIZE=0
- HMSG$="Unpacking error! (Code:"+Str$(Errtrap)+")"
- End If
- Else
- HMSG$="Data checksum error!" : FLSIZE=0
- End If
- End If
- '
- ' if (unpacked) data checksum okay, save file
- '
- If FLSIZE
- If Bank Checksum(20)=FLSUMM : MS$="Okay." : OKAY=True
- If NOSIMULATE : OKAY=False : TT$=Path$(FILE$)
- If Not Exist(TT$) : CREATE_DIR[TT$] : End If
- MS$="Saving... " : Print MS$; : HMSG$=HMSG$+MS$
- AD=Start(20) : Trap Bsave FILE$,AD To AD+FLSIZE
- If Errtrap=0 : Set Object Date FILE$,FLDATE,FLTIME
- Protect Object FILE$,FLPROT : MS$="Done." : OKAY=True
- Else : MS$="Failed! (Code:"+Str$(Errtrap)+")" : End If
- End If : HMSG$=HMSG$+MS$ : Print MS$; : Wait 10
- Else
- HMSG$="File checksum error!"
- End If
- End If
- End If : HISTORYENTRY[" "+HMSG$+LF$]
- '
- End Proc[OKAY]
- '
- ' History Procedures
- '
- Procedure HISTORY_SAVE
- '
- ' save history messages
- '
- FL$=Fsel$("*.TXT",BKNAME$+"Log.TXT","Save history messages")
- If FL$>"" : Open Out 2,FL$ : AD=HISTROOTADRS
- While AD
- Print #2,Peek$(AD+8,Leek(AD),C0$);LF$; : AD=Leek(AD+4)
- Wend : Close 2
- End If
- End Proc
- Procedure HISTORYENTRY[MS$]
- '
- ' add new history message (note: GLOBAL address variables!!!)
- '
- ALLOCMEM[Len(MS$)+8]
- If Param : ADRS=Param : Inc NUMHIST
- If HISTADRS : Loke HISTADRS+4,ADRS : End If : Poke$ ADRS+8,MS$
- If HISTROOTADRS=0 : HISTROOTADRS=ADRS : End If : HISTADRS=ADRS
- End If
- End Proc
- Procedure DISPLAY_HISTORY[HTOP]
- '
- ' display backup history messages
- '
- MOVE_TO_ENTRY[HISTROOTADRS,HTOP] : AD=Param : Paper 0 : Pen 3
- For YP=4 To 11 : TT$=Peek$(AD+8,64,C0$) : LL=Len(TT$)
- If Right$(TT$,1)=LF$ : Dec LL : TT$=Left$(TT$,LL) : End If
- Print At(7,YP);TT$;Space$(64-LL) : AD=Leek(AD+4) : Exit If AD=0
- Next : Paper 6 : Pen 2
- End Proc
- '
- ' Directory Tree Procedures
- '
- Procedure MAKE_DIRTREE[ROOT$]
- '
- ' dynamically build directory tree starting at ROOT$
- ' returns TREEROOT on success, 0 if user abort, -1 if out of memory
- '
- ' Important vars:
- ' TREEROOT ..... pointer to created directory tree structure
- ' TREETHIS ..... pointer to current dir item of tree structure
- ' STACKADR ..... pointer to top element of "dirs-to-do" stack
- ' DRLSTADR ..... pointer to first element of sub dirs list
- '
- ' Directory stack:
- ' NALLOC (4,+ 0) ... bytes allocated for this item (ALLOCMEM)
- ' PRVPTR (4.+ 4) ... address to previous item (it's a stack!)
- ' PARPTR (4,+ 8) ... address to parent item of dir tree
- ' DNAME$ (D,+12) ... tree structure, », complete path of dir
- '
- QUIT=False : TT$="»"+ROOT$ : ALLOCMEM[Len(TT$)+9] : ADRS=Param
- Poke$ ADRS+12,TT$ : STACKADR=ADRS : TREEROOT=0 : TREETHIS=0
- MXTREE=0 : NUMDIRS=0 : NUMFILES=0 : NUMBYTES=0 : SELBYTES=0
- '
- ' as long as there are items on stack read and remove top element
- '
- While STACKADR
- Inc MXTREE : AD=STACKADR : TT$=Peek$(AD+12,Leek(AD),C0$)
- PARNTADR=Leek(AD+8) : PS=Instr(TT$,"»") : TREE$=Left$(TT$,PS-1)+"»"
- DR$=Mid$(TT$,PS+1) : STACKADR=Leek(STACKADR+4) : DEALLOCMEM[AD]
- If TREEROOT : TT$=Filename$(DR$) Else TT$=DR$ : End If : NBYTES=0
- '
- ' read directory, put dirs and files on seperate lists
- '
- TR$=TREE$+TT$+C0$ : If Right$(DR$,1)<>":" : DR$=DR$+"/" : End If
- NDIRS=0 : NFILES=0 : DRLSTADR=0 : FLISTADR=0 : Examine Dir DR$
- Do
- FL$=Examine Next$ : Exit If FL$=""
- If Object Type>0 : Inc NDIRS
- '
- ' sort directory into linked list of sub dirs (descending)
- '
- ALLOCMEM[Len(FL$)+5] : ADRS=Param : Poke$ ADRS+8,FL$
- If DRLSTADR : STRT=DRLSTADR : PREV=0 : FL$=Upper$(FL$)
- While Upper$(Peek$(STRT+8,Leek(STRT),C0$))>FL$
- PREV=STRT : STRT=Leek(STRT+4) : Exit If STRT=0
- Wend
- If PREV
- Loke PREV+4,ADRS : If STRT : Loke ADRS+4,STRT : End If
- Else : DRLSTADR=ADRS : Loke ADRS+4,STRT : End If
- Else
- DRLSTADR=ADRS
- End If
- Else
- '
- ' sort file into linked list (ascending)
- '
- ALLOCMEM[Len(FL$)+13] : ADRS=Param : Add NBYTES,Object Size
- Loke ADRS+8,Object Size : Poke$ ADRS+12,FL$ : Inc NFILES
- If FLISTADR : STRT=FLISTADR : PREV=0 : FL$=Upper$(FL$)
- While Upper$(Peek$(STRT+12,Leek(STRT),C0$))<FL$
- PREV=STRT : STRT=Leek(STRT+4) : Exit If STRT=0
- Wend
- If PREV
- Loke PREV+4,ADRS : If STRT : Loke ADRS+4,STRT : End If
- Else : FLISTADR=ADRS : Loke ADRS+4,STRT : End If
- Else
- FLISTADR=ADRS
- End If
- End If
- Loop
- '
- ' add new entry to directory tree; update counters
- '
- ALLOCMEM[Len(TR$)+NFILES+24] : ADRS=Param : NR=NFILES+1
- If TREETHIS : Loke TREETHIS+4,ADRS Else TREEROOT=ADRS : End If
- Loke ADRS+8,PARNTADR : Loke ADRS+12,FLISTADR : Loke ADRS+16,NBYTES
- Doke ADRS+24,NFILES : Poke ADRS+26,PS : TREETHIS=ADRS : AD=ADRS+27
- While NR : Poke AD,46 : Inc AD : Dec NR : Wend : Poke$ AD,TR$
- Add NUMDIRS,NDIRS : Add NUMFILES,NFILES : Add NUMBYTES,NBYTES
- '
- ' check if any sub dirs found; if so recalcuate tree structure
- '
- If DRLSTADR
- NR=Len(TREE$)-1 : TR$=""
- While NR : AC=Asc(Mid$(TREE$,NR)) : Dec NR
- If AC=32 or AC=45 : TR$=" "+TR$ Else TR$="|"+TR$ : End If
- Wend
- '
- ' put sub dirs on stack; free memory from sub dir items
- '
- STRT=DRLSTADR : DR$="-»"+DR$
- Repeat : TT$=TR$+DR$+Peek$(STRT+8,Leek(STRT),C0$)
- ALLOCMEM[Len(TT$)+9] : ADRS=Param : Left$(DR$,1)="+"
- Loke ADRS+4,STACKADR : Loke ADRS+8,TREETHIS : Poke$ ADRS+12,TT$
- STACKADR=ADRS : AD=STRT : STRT=Leek(STRT+4) : DEALLOCMEM[AD]
- Until STRT=0
- End If
- '
- ' check abort; check memory: cancel if lower than 64K left
- '
- Print At(30,14); Using "######";NUMDIRS
- Print At(46,14); Using "########";NUMFILES
- NR=Chip Free+Fast Free : Print At(37,16); Using "########";NR
- QUIT=Dialog(3) : If NR<65536 : QUIT=True : End If : Exit If QUIT
- Wend
- '
- ' user abort ? -> free dir stack and already created dir tree
- '
- If QUIT : DELETE_DIRTREE[TREEROOT] : DELETE_LIST[STACKADR]
- If QUIT<0 : TREEROOT=-1 Else TREEROOT=0 : End If
- End If
- '
- End Proc[TREEROOT]
- Procedure DELETE_DIRTREE[ADRS]
- '
- ' removes directory tree (with file list) starting at ADRS
- '
- While ADRS : DELETE_LIST[Leek(ADRS+12)]
- AD=ADRS : ADRS=Leek(ADRS+4) : DEALLOCMEM[AD]
- Wend
- End Proc
- Procedure CREATE_DIRTREE_PATH[ADRS]
- '
- ' extract full path name of the entry at ADRS (ends with "/")
- '
- While ADRS
- TT$=Peek$(ADRS+Deek(ADRS+24)+28,Leek(ADRS),C0$)
- If Right$(TT$,1)<>":" : TT$=TT$+"/" : End If
- PT$=Mid$(TT$,Instr(TT$,"»")+1)+PT$ : ADRS=Leek(ADRS+8)
- Wend
- End Proc[PT$]
- Procedure MOVE_TO_ENTRY[ROOTADRS,DTOP]
- '
- ' moves to entry DTOP of directory tree or file list
- '
- If ROOTADRS>0 : AD=ROOTADRS
- While DTOP : AD=Leek(AD+4) : Dec DTOP : Exit If AD=0 : Wend
- End If
- End Proc[AD]
- '
- ' System Memory Procedures
- '
- Procedure ALLOCMEM[BYTE]
- '
- ' allocate memory from system:
- ' -> add 4 bytes for number of bytes allocated information
- ' -> attributes: ANY =0 , PUBLIC =1 , CLEAR =65536 ==> $10001
- ' -> write number of bytes into first 4 bytes (NEVER CHANGE!)
- ' RETURN: start address, or 0 if memory block not available
- '
- BYTE=(BYTE+7) and $FFFFFFFC : Dreg(0)=BYTE : Dreg(1)=$10001
- ADRS=Execall(-198) : If ADRS : Loke ADRS,BYTE : End If
- '
- End Proc[ADRS]
- Procedure DEALLOCMEM[ADRS]
- '
- ' free memory allocated by procedure ALLOCMEM[] above
- ' -> first read allocated bytes from first 4 bytes (CAUTION!)
- ' -> free memory (read required addresses before calling this)
- '
- If ADRS : Areg(1)=ADRS : Dreg(0)=Leek(ADRS) : RT=Execall(-210) : End If
- '
- End Proc
- Procedure DELETE_LIST[ADRS]
- '
- ' remove any linked list created with ALLOCMEM[] using DEALLOCMEM[]
- ' -> IMPORTANT: first 4 bytes are amount of bytes allocated
- ' -> IMPORTANT: second 4 bytes are address to next item
- '
- While ADRS>0 : AD=ADRS : ADRS=Leek(ADRS+4) : DEALLOCMEM[AD] : Wend
- '
- End Proc
- Procedure FLOPPYADDBUFFERS[NR]
- '
- ' call DOS function: add NR buffers for internal floppy "DF0:"
- ' RETURN: number of buffers, or 0 if failed (drive maybe busy ?)
- '
- TT$="DF0:" : Dreg(1)=Varptr(TT$)
- Dreg(2)=NR : RS=Doscall(Lvo("AddBuffers"))
- '
- ' if function returns -1, IoErr has number of buffers (obsolete?)
- '
- If RS<0 : RS=Doscall(Lvo("IoErr")) : End If
- '
- End Proc[RS]
- '
- ' Global Procedures
- '
- Procedure ALERT[MESS$]
- '
- ' alert program; interrupt Dialog Box with <CTRL>+'C' and Break Off !!!
- '
- Dialog Open 6,2 : Vdialog$(6,0)=MESS$ : SL=Dialog Run(6) : Wait Vbl
- Repeat : Multi Wait : SL=Vdialog(6,1) : Until SL : Dialog Close 6
- End Proc[SL]
- Procedure INFO[MESS$]
- '
- ' info box; interrupt Dialog Box with <CTRL>+'C' and Break Off !!!
- '
- Dialog Open 7,3 : Vdialog$(7,0)=MESS$ : RR=Dialog Run(7) : Wait Vbl
- Repeat : Multi Wait : Until Mouse Click or Inkey$>"" : Dialog Close 7
- End Proc
-
-